#Load packages

library(data.table)
library(tidyr)
library(haven)
library(ggplot2)
library(dplyr)
library(gridExtra)
library(lmtest)

#Add data GPS

# Einlesen des Datensets
gps_data <- haven::read_dta("/Users/laurabazzigher/Documents/GitHub/risk_wvs/data/dataset/GPS_dataset_individual_level/individual_new.dta")

# Anzeige der ersten Zeilen des Datensets
head(country_data)

Number of courtries

# Determine the number of different countries
number_of_countries <- length(unique(gps_data$country))

# Display the number of different countries
number_of_countries
[1] 76

Clean the data from missing values

# Clean the data by removing records with missing values
cleaned_data <- gps_data %>%
  drop_na(country, isocode, risktaking, gender, age)

# Calculate the number of records removed per variable
records_removed_per_variable <- colSums(is.na(gps_data)) - colSums(is.na(cleaned_data))

# Display the cleaned data
cleaned_data

# Display the number of records removed per variable
records_removed_per_variable
         country          isocode             ison           region         language             date 
               0                0                0                0                0                0 
       id_gallup              wgt         patience       risktaking         posrecip         negrecip 
               0                0              190              634               32              247 
        altruism            trust subj_math_skills           gender              age 
              74              163              132                0              276 

List of all variable

# List all variables
variable_list <- names(cleaned_data) # OR colnames(your_data)

# Display the list of variables
print(variable_list)
 [1] "country"          "isocode"          "ison"             "region"           "language"        
 [6] "date"             "id_gallup"        "wgt"              "patience"         "risktaking"      
[11] "posrecip"         "negrecip"         "altruism"         "trust"            "subj_math_skills"
[16] "gender"           "age"             

Variance of some Items

# Calculate the variance of the "patience" variable
variance_patience <- var(cleaned_data$patience, na.rm = TRUE)
variance_risktaking <- var(cleaned_data$risktaking, na.rm = TRUE)
variance_age <- var(cleaned_data$age, na.rm = TRUE)

# Display the variance of the "patience" variable
variance_patience
[1] 1.000596
variance_risktaking
[1] 1.000054
variance_age
[1] 304.2504

Histogram of some variables

hist(cleaned_data$age, main = "Histogram of Age", xlab = "age", ylab = "Frequency")

hist(cleaned_data$patience, main = "Histogram of patience", xlab = "patience", ylab = "Frequency")

hist(cleaned_data$risktaking, main = "Histogram of risktaking", xlab = "risktaking", ylab = "Frequency")

Boxplot of some variables

boxplot(cleaned_data$age, main = "Boxplot of Age")

boxplot(cleaned_data$patience, main = "Boxplot of Patience")

boxplot(cleaned_data$risktaking, main = "Boxplot of Risktaking")

All about the age

# Age Range
age_min <- min(cleaned_data$age, na.rm = TRUE)
age_max <- max(cleaned_data$age, na.rm = TRUE)

# Average Age
average_age <- mean(cleaned_data$age, na.rm = TRUE)

# Median Age
median_age <- median(cleaned_data$age, na.rm = TRUE)

# Display the age statistics
cat("Age Range: ", age_min, " to ", age_max, "\n")
Age Range:  15  to  99 
cat("Average Age: ", average_age, "\n")
Average Age:  41.73605 
cat("Median Age: ", median_age, "\n")
Median Age:  40 

All about the gender

# Calculate the counts of females (gender = 1) and males (gender = 2)
gender_counts <- table(cleaned_data$gender)

# Display the counts
cat("Number of Females: ", gender_counts[1], "\n")
Number of Females:  36024 
cat("Number of Males: ", gender_counts[2], "\n")
Number of Males:  43415 

Table with country and gender

# Create a table that breaks down the number of participants by country and gender
gender_by_country <- xtabs(~ country + gender, data = cleaned_data)

# Rename columns and rows for better readability
colnames(gender_by_country) <- c("Female", "Male")
rownames(gender_by_country) <- unique(cleaned_data$country)

# Display the table
gender_by_country
                      gender
country                Female Male
  Turkey                  499  498
  France                  537  485
  Netherlands             383  604
  Spain                   434  554
  Italy                   382  609
  Poland                  480  513
  Hungary                 408  582
  Czech Republic          416  575
  Romania                 406  594
  Sweden                  402  596
  Greece                  327  671
  China                   485  515
  Venezuela               480  497
  Kenya                   411  592
  Tanzania               1188 1338
  Israel                  366  630
  Ghana                   448  551
  Uganda                  385  559
  Malawi                  413  578
  Australia               517  502
  Sri Lanka               350  645
  Cambodia                456  538
  Botswana                415  572
  Rwanda                  447  539
  Afghanistan             466  521
  Georgia                 510  490
  Kazakhstan              438  561
  Moldova                 416  578
  Ukraine                 253  250
  Cameroon                402  601
  Zimbabwe               1379 1134
  Costa Rica              456  539
  Argentina              1301 1162
  Austria                 496  469
  Bolivia                 476  503
  Bosnia Herzegovina      409  575
  Chile                   471  525
  Colombia                499  493
  Croatia                 366  596
  Estonia                 516  482
  Finland                 427  560
  Guatemala               412  588
  Haiti                   528  470
  Lithuania               424  566
  Nicaragua               459  532
  Peru                    487  497
  Portugal                450  545
  Serbia                  559  436
  Suriname                496  498
  Switzerland             455  533
  United States           425  575
  Morocco                 393  594
  Saudi Arabia            383  592
  Jordan                  409  541
  Pakistan                489  958
  Indonesia               486  514
  Bangladesh              519  516
  United Kingdom          473  538
  Germany                 448  550
  Iran                    459  521
  Japan                   444  554
  India                   419  573
  Brazil                  240  250
  Mexico                  468  527
  Nigeria                 396  597
  South Africa            544  455
  Canada                  360  639
  Philippines             476  511
  Vietnam                 546  454
  Thailand                316  666
  South Korea             440  552
  Russia                  470  514
  Algeria                 516  529
  Iraq                    388  608
  United Arab Emirates    427  550
  Egypt                   504  496

Create a table with the following information: country, isocode, n (count of participants), female percentage (%), mean age, age range, and risktaking

# Group the data by country
table_data <- gps_data %>%
  group_by(country, isocode) %>%
  summarize(
    n = n(),
    female_percentage = mean(gender == 1) * 100,
    mean_age = mean(age, na.rm = TRUE),
    age_range = paste(min(age, na.rm = TRUE), "-", max(age, na.rm = TRUE)),
    mean_risktaking = mean(risktaking, na.rm = TRUE)
  )
`summarise()` has grouped output by 'country'. You can override using the `.groups` argument.
# Display the table
table_data

Create a new column “age_group” with the age categories

cleaned_data$agecat <- cut(
  cleaned_data$age,
  breaks = c(15, 20, 30, 40, 50, 60, 70, 80, Inf), # The category boundaries
  labels = c("15-19", "20-29", "30-39", "40-49", "50-59", "60-69", "70-79", "80+"), # The category labels
  right = FALSE # Left end (inclusive), right end (exclusive)
)

# Display the new column
head(cleaned_data)

Number of participants in each age category

# number of participants in each age category
agecat_counts <- table(cleaned_data$agecat)

# Display the number of participants in the age categories
print(agecat_counts)

15-19 20-29 30-39 40-49 50-59 60-69 70-79   80+ 
 6888 16872 15905 13583 11374  8570  4688  1559 

Perform a correlation analysis on variables patience, risktaking, altruism and trust

# Calculate the correlation matrix with NA removal
correlation_matrix <- cor(cleaned_data[, c("patience", "risktaking", "altruism", "trust")], use = "pairwise.complete.obs")

# Print the correlation matrix
print(correlation_matrix)
             patience risktaking   altruism      trust
patience   1.00000000 0.20573586 0.08397351 0.06404146
risktaking 0.20573586 1.00000000 0.09524941 0.03517175
altruism   0.08397351 0.09524941 1.00000000 0.16734183
trust      0.06404146 0.03517175 0.16734183 1.00000000

checking the assumptions in a linear regression

# Scatterplot to check for linearity
ggplot(cleaned_data, aes(x = age, y = risktaking)) +
  geom_point() +
  geom_smooth(method = "lm", se = FALSE, color = "blue") +
  labs(title = "Scatterplot for Linearity Check")

# Residual vs. Fitted plot to check for homoskedasticity
model <- lm(risktaking ~ age, data = cleaned_data)
ggplot() +
  geom_point(aes(x = fitted(model), y = residuals(model))) +
  geom_hline(yintercept = 0, linetype = "dashed", color = "red") +
  labs(title = "Residuals vs. Fitted Values for Homoskedasticity Check")

# Q-Q plot to check for normality of residuals
qqnorm(residuals(model))
qqline(residuals(model))

# Correlation matrix to check for multicollinearity
cor(cleaned_data[c("age", "risktaking")])
                  age risktaking
age         1.0000000 -0.2405333
risktaking -0.2405333  1.0000000
# Durbin-Watson test for autocorrelation
dwtest(model)

    Durbin-Watson test

data:  model
DW = 1.5415, p-value < 2.2e-16
alternative hypothesis: true autocorrelation is greater than 0
# Residual vs. Leverage plot to check for outliers
ggplot() +
  geom_point(aes(x = hatvalues(model), y = residuals(model))) +
  geom_hline(yintercept = 0, linetype = "dashed", color = "red") +
  labs(title = "Residuals vs. Leverage for Outlier Check")

#Preparing for linear regression

# Check for missing values in 'Country' and 'Risktaking' columns
missing_country <- anyNA(cleaned_data$country)
missing_risktaking <- anyNA(cleaned_data$risktaking)

# Print the results
cat("Missing values in 'Country': ", missing_country, "\n")
Missing values in 'Country':  FALSE 
cat("Missing values in 'Risktaking': ", missing_risktaking, "\n")
Missing values in 'Risktaking':  FALSE 
# Clean the data by removing records with missing values
cleaned_data <- gps_data %>%
  drop_na(country, risktaking, age)

# Split the data by country and perform linear regression for each country
regression_results <- cleaned_data %>%
  group_by(country) %>%
  do(model = lm(risktaking ~ age, data = .)) %>%
  summarize(
    country = first(country),
    intercept = summary(model)$coefficients[1],
    slope = summary(model)$coefficients[2],
    r_squared = summary(model)$r.squared
  )

# Display regression results for each country
print(regression_results)

analyze the results by using “Balkendiagramm

ggplot(data = regression_results, aes(x = country, y = intercept)) +
  geom_bar(stat = "identity", fill = "blue") +
  labs(title = "Intercepts for Risktaking by Country", x = "Country", y = "Intercept Value") +
  theme(axis.text.x = element_text(angle = 90, hjust = 1))

View the countries with intercept values over 0.75

high_intercept_countries <- subset(regression_results, intercept > 0.75)

# View the countries with intercept values over 0.75
print(high_intercept_countries)

Scatterplots for ‘high_intercept_countries’ contains the top 17 countries

# Create scatterplots with regression lines for countries with intercept > 0.75 and smaller points
plots <- lapply(1:nrow(regression_results), function(i) {
  country <- regression_results$country[i]
  intercept <- regression_results$intercept[i]
  
  if (intercept > 0.75) {
    p <- ggplot(subset(cleaned_data, country == country), aes(x = age, y = risktaking)) +
      geom_point(size = 0.5) +  # Set the size to a smaller value (e.g., 2)
      geom_smooth(method = "lm", formula = y ~ x, se = FALSE, color = "blue") +
      labs(title = paste("Linear Regression for", country),
           subtitle = paste("Intercept:", round(intercept, 2)))
    print(p)
  }
})


# Save the plots in a directory
dir.create("individual_country_plots", showWarnings = FALSE)
setwd("individual_country_plots")
Warning: The working directory was changed to /Users/laurabazzigher/Documents/GitHub/risk_wvs/code/individual_country_plots inside a notebook chunk. The working directory will be reset when the chunk is finished running. Use the knitr root.dir option in the setup chunk to change the working directory for notebook chunks.
for (i in seq_along(plots)) {
  filename <- paste0("plot_", i, ".png")
  ggsave(filename, plot = plots[[i]], width = 8, height = 6)
}


# Switch back to the original working directory
setwd("..")

print("Individual plots for countries with intercept > 0.75 and smaller points are saved in the 'individual_country_plots' directory.")
[1] "Individual plots for countries with intercept > 0.75 and smaller points are saved in the 'individual_country_plots' directory."

Create scatterplots with regression lines for individual countries

regression_results <- data.frame(
  country = c("Algeria", "Argentina", "Austria"),
  intercept = c(0.92053422, 0.51698822, 0.42606684),
  slope = c(-0.0146641801, -0.0115569623, -0.0108763042),
  r_squared = c(5.232529e-02, 5.638271e-02, 3.539810e-02    )
)

# Create scatterplots with regression lines for each country
plots <- lapply(seq_len(nrow(regression_results)), function(i) {
  country <- regression_results$country[i]
  intercept <- regression_results$intercept[i]
  slope <- regression_results$slope[i]
  r_squared <- regression_results$r_squared[i]
  
  p <- ggplot(subset(cleaned_data, country == country), aes(x = age, y = risktaking)) +
    geom_point() +
    geom_smooth(method = "lm", formula = y ~ x, se = FALSE, color = "blue") +
    labs(title = paste("Linear Regression for", country),
         subtitle = paste("Intercept:", round(intercept, 2),
                           "Slope:", round(slope, 2),
                           "R-squared:", round(r_squared, 2)))
  print(p)
})


# Save the plots in a directory
dir.create("individual_country_plots", showWarnings = FALSE)
setwd("individual_country_plots")
Warning: The working directory was changed to /Users/laurabazzigher/Documents/GitHub/risk_wvs/code/individual_country_plots inside a notebook chunk. The working directory will be reset when the chunk is finished running. Use the knitr root.dir option in the setup chunk to change the working directory for notebook chunks.
for (i in seq_along(plots)) {
  filename <- paste0("plot_", i, ".png")
  ggsave(filename, plot = plots[[i]], width = 8, height = 6)
}


# Switch back to the original working directory
setwd("..")

print("Individual plots are saved in the 'individual_country_plots' directory.")
[1] "Individual plots are saved in the 'individual_country_plots' directory."

Create a scatterplot with separate regression lines for each country

# Calculate the overall regression line
overall_lm <- lm(risktaking ~ age, data = cleaned_data) # Regression over all countries

ggplot(cleaned_data, aes(x = age, y = risktaking, color = country)) +
  geom_point(size = 0.2) +                           # Adjust point size
  geom_smooth(method = "lm", se = FALSE, size = 0.5, linetype = "solid") + # Adjust line size and type
  labs(title = "Scatterplot with Regression Lines for risktaking and age by Country", 
       x = "Age", y = "Risktaking") +
  theme(legend.position = "bottom",              # Move the legend below the graph
        legend.key.size = unit(0.1, "in"))      # Adjust the size of the legend key

Scatterplot with include both individual country regression lines and an overall regression line

# Calculate the overall regression line
overall_lm <- lm(risktaking ~ age, data = cleaned_data)

# Create a scatterplot with separate regression lines for each country
# and an overall regression line
ggplot(cleaned_data, aes(x = age, y = risktaking, color = country)) +
  geom_point(size = 0.5) +                      # Adjust point size
  geom_smooth(method = "lm", se = FALSE, size = 0.5) + # Solid line for individual countries
  geom_abline(intercept = coef(overall_lm)[1], slope = coef(overall_lm)[2], 
              color = "red", size = 1) + # Add the overall regression line in red
  labs(title = "Scatterplot with Regression Lines for risktaking and age by Country", 
       x = "Age", y = "Risktaking") +
  theme(legend.position = "bottom",          # Move the legend below the graph
        legend.key.size = unit(0.1, "in"))  # Adjust the size of the legend key

LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKI0xvYWQgcGFja2FnZXMgCmBgYHtyfQpsaWJyYXJ5KGRhdGEudGFibGUpCmxpYnJhcnkodGlkeXIpCmxpYnJhcnkoaGF2ZW4pCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShkcGx5cikKbGlicmFyeShncmlkRXh0cmEpCmxpYnJhcnkobG10ZXN0KQpgYGAKCgojQWRkIGRhdGEgR1BTCmBgYHtyfQojIEVpbmxlc2VuIGRlcyBEYXRlbnNldHMKZ3BzX2RhdGEgPC0gaGF2ZW46OnJlYWRfZHRhKCIvVXNlcnMvbGF1cmFiYXp6aWdoZXIvRG9jdW1lbnRzL0dpdEh1Yi9yaXNrX3d2cy9kYXRhL2RhdGFzZXQvR1BTX2RhdGFzZXRfaW5kaXZpZHVhbF9sZXZlbC9pbmRpdmlkdWFsX25ldy5kdGEiKQoKIyBBbnplaWdlIGRlciBlcnN0ZW4gWmVpbGVuIGRlcyBEYXRlbnNldHMKaGVhZChjb3VudHJ5X2RhdGEpCmBgYAojIE51bWJlciBvZiBjb3VydHJpZXMgCmBgYHtyfQojIERldGVybWluZSB0aGUgbnVtYmVyIG9mIGRpZmZlcmVudCBjb3VudHJpZXMKbnVtYmVyX29mX2NvdW50cmllcyA8LSBsZW5ndGgodW5pcXVlKGdwc19kYXRhJGNvdW50cnkpKQoKIyBEaXNwbGF5IHRoZSBudW1iZXIgb2YgZGlmZmVyZW50IGNvdW50cmllcwpudW1iZXJfb2ZfY291bnRyaWVzCmBgYAoKCiMgQ2xlYW4gdGhlIGRhdGEgZnJvbSBtaXNzaW5nIHZhbHVlcwpgYGB7cn0KIyBDbGVhbiB0aGUgZGF0YSBieSByZW1vdmluZyByZWNvcmRzIHdpdGggbWlzc2luZyB2YWx1ZXMKY2xlYW5lZF9kYXRhIDwtIGdwc19kYXRhICU+JQogIGRyb3BfbmEoY291bnRyeSwgaXNvY29kZSwgcmlza3Rha2luZywgZ2VuZGVyLCBhZ2UpCgojIENhbGN1bGF0ZSB0aGUgbnVtYmVyIG9mIHJlY29yZHMgcmVtb3ZlZCBwZXIgdmFyaWFibGUKcmVjb3Jkc19yZW1vdmVkX3Blcl92YXJpYWJsZSA8LSBjb2xTdW1zKGlzLm5hKGdwc19kYXRhKSkgLSBjb2xTdW1zKGlzLm5hKGNsZWFuZWRfZGF0YSkpCgojIERpc3BsYXkgdGhlIGNsZWFuZWQgZGF0YQpjbGVhbmVkX2RhdGEKCiMgRGlzcGxheSB0aGUgbnVtYmVyIG9mIHJlY29yZHMgcmVtb3ZlZCBwZXIgdmFyaWFibGUKcmVjb3Jkc19yZW1vdmVkX3Blcl92YXJpYWJsZQpgYGAKCiMgTGlzdCBvZiBhbGwgdmFyaWFibGUKYGBge3J9CiMgTGlzdCBhbGwgdmFyaWFibGVzCnZhcmlhYmxlX2xpc3QgPC0gbmFtZXMoY2xlYW5lZF9kYXRhKSAjIE9SIGNvbG5hbWVzKHlvdXJfZGF0YSkKCiMgRGlzcGxheSB0aGUgbGlzdCBvZiB2YXJpYWJsZXMKcHJpbnQodmFyaWFibGVfbGlzdCkKYGBgCgojIFZhcmlhbmNlIG9mIHNvbWUgSXRlbXMKYGBge3J9CiMgQ2FsY3VsYXRlIHRoZSB2YXJpYW5jZSBvZiB0aGUgInBhdGllbmNlIiB2YXJpYWJsZQp2YXJpYW5jZV9wYXRpZW5jZSA8LSB2YXIoY2xlYW5lZF9kYXRhJHBhdGllbmNlLCBuYS5ybSA9IFRSVUUpCnZhcmlhbmNlX3Jpc2t0YWtpbmcgPC0gdmFyKGNsZWFuZWRfZGF0YSRyaXNrdGFraW5nLCBuYS5ybSA9IFRSVUUpCnZhcmlhbmNlX2FnZSA8LSB2YXIoY2xlYW5lZF9kYXRhJGFnZSwgbmEucm0gPSBUUlVFKQoKIyBEaXNwbGF5IHRoZSB2YXJpYW5jZSBvZiB0aGUgInBhdGllbmNlIiB2YXJpYWJsZQp2YXJpYW5jZV9wYXRpZW5jZQp2YXJpYW5jZV9yaXNrdGFraW5nCnZhcmlhbmNlX2FnZQpgYGAKIyBIaXN0b2dyYW0gb2Ygc29tZSB2YXJpYWJsZXMKYGBge3J9Cmhpc3QoY2xlYW5lZF9kYXRhJGFnZSwgbWFpbiA9ICJIaXN0b2dyYW0gb2YgQWdlIiwgeGxhYiA9ICJhZ2UiLCB5bGFiID0gIkZyZXF1ZW5jeSIpCmhpc3QoY2xlYW5lZF9kYXRhJHBhdGllbmNlLCBtYWluID0gIkhpc3RvZ3JhbSBvZiBwYXRpZW5jZSIsIHhsYWIgPSAicGF0aWVuY2UiLCB5bGFiID0gIkZyZXF1ZW5jeSIpCmhpc3QoY2xlYW5lZF9kYXRhJHJpc2t0YWtpbmcsIG1haW4gPSAiSGlzdG9ncmFtIG9mIHJpc2t0YWtpbmciLCB4bGFiID0gInJpc2t0YWtpbmciLCB5bGFiID0gIkZyZXF1ZW5jeSIpCmBgYAojIEJveHBsb3Qgb2Ygc29tZSB2YXJpYWJsZXMKYGBge3J9CmJveHBsb3QoY2xlYW5lZF9kYXRhJGFnZSwgbWFpbiA9ICJCb3hwbG90IG9mIEFnZSIpCmJveHBsb3QoY2xlYW5lZF9kYXRhJHBhdGllbmNlLCBtYWluID0gIkJveHBsb3Qgb2YgUGF0aWVuY2UiKQpib3hwbG90KGNsZWFuZWRfZGF0YSRyaXNrdGFraW5nLCBtYWluID0gIkJveHBsb3Qgb2YgUmlza3Rha2luZyIpCmBgYAojIEFsbCBhYm91dCB0aGUgYWdlCmBgYHtyfQojIEFnZSBSYW5nZQphZ2VfbWluIDwtIG1pbihjbGVhbmVkX2RhdGEkYWdlLCBuYS5ybSA9IFRSVUUpCmFnZV9tYXggPC0gbWF4KGNsZWFuZWRfZGF0YSRhZ2UsIG5hLnJtID0gVFJVRSkKCiMgQXZlcmFnZSBBZ2UKYXZlcmFnZV9hZ2UgPC0gbWVhbihjbGVhbmVkX2RhdGEkYWdlLCBuYS5ybSA9IFRSVUUpCgojIE1lZGlhbiBBZ2UKbWVkaWFuX2FnZSA8LSBtZWRpYW4oY2xlYW5lZF9kYXRhJGFnZSwgbmEucm0gPSBUUlVFKQoKIyBEaXNwbGF5IHRoZSBhZ2Ugc3RhdGlzdGljcwpjYXQoIkFnZSBSYW5nZTogIiwgYWdlX21pbiwgIiB0byAiLCBhZ2VfbWF4LCAiXG4iKQpjYXQoIkF2ZXJhZ2UgQWdlOiAiLCBhdmVyYWdlX2FnZSwgIlxuIikKY2F0KCJNZWRpYW4gQWdlOiAiLCBtZWRpYW5fYWdlLCAiXG4iKQpgYGAKCiMgQWxsIGFib3V0IHRoZSBnZW5kZXIKYGBge3J9CiMgQ2FsY3VsYXRlIHRoZSBjb3VudHMgb2YgZmVtYWxlcyAoZ2VuZGVyID0gMSkgYW5kIG1hbGVzIChnZW5kZXIgPSAyKQpnZW5kZXJfY291bnRzIDwtIHRhYmxlKGNsZWFuZWRfZGF0YSRnZW5kZXIpCgojIERpc3BsYXkgdGhlIGNvdW50cwpjYXQoIk51bWJlciBvZiBGZW1hbGVzOiAiLCBnZW5kZXJfY291bnRzWzFdLCAiXG4iKQpjYXQoIk51bWJlciBvZiBNYWxlczogIiwgZ2VuZGVyX2NvdW50c1syXSwgIlxuIikKYGBgCgojIFRhYmxlIHdpdGggY291bnRyeSBhbmQgZ2VuZGVyCmBgYHtyfQojIENyZWF0ZSBhIHRhYmxlIHRoYXQgYnJlYWtzIGRvd24gdGhlIG51bWJlciBvZiBwYXJ0aWNpcGFudHMgYnkgY291bnRyeSBhbmQgZ2VuZGVyCmdlbmRlcl9ieV9jb3VudHJ5IDwtIHh0YWJzKH4gY291bnRyeSArIGdlbmRlciwgZGF0YSA9IGNsZWFuZWRfZGF0YSkKCiMgUmVuYW1lIGNvbHVtbnMgYW5kIHJvd3MgZm9yIGJldHRlciByZWFkYWJpbGl0eQpjb2xuYW1lcyhnZW5kZXJfYnlfY291bnRyeSkgPC0gYygiRmVtYWxlIiwgIk1hbGUiKQpyb3duYW1lcyhnZW5kZXJfYnlfY291bnRyeSkgPC0gdW5pcXVlKGNsZWFuZWRfZGF0YSRjb3VudHJ5KQoKIyBEaXNwbGF5IHRoZSB0YWJsZQpnZW5kZXJfYnlfY291bnRyeQpgYGAKIyBDcmVhdGUgYSB0YWJsZSB3aXRoIHRoZSBmb2xsb3dpbmcgaW5mb3JtYXRpb246IGNvdW50cnksIGlzb2NvZGUsIG4gKGNvdW50IG9mIHBhcnRpY2lwYW50cyksIGZlbWFsZSBwZXJjZW50YWdlICglKSwgbWVhbiBhZ2UsIGFnZSByYW5nZSwgYW5kIHJpc2t0YWtpbmcKYGBge3J9CiMgR3JvdXAgdGhlIGRhdGEgYnkgY291bnRyeQp0YWJsZV9kYXRhIDwtIGdwc19kYXRhICU+JQogIGdyb3VwX2J5KGNvdW50cnksIGlzb2NvZGUpICU+JQogIHN1bW1hcml6ZSgKICAgIG4gPSBuKCksCiAgICBmZW1hbGVfcGVyY2VudGFnZSA9IG1lYW4oZ2VuZGVyID09IDEpICogMTAwLAogICAgbWVhbl9hZ2UgPSBtZWFuKGFnZSwgbmEucm0gPSBUUlVFKSwKICAgIGFnZV9yYW5nZSA9IHBhc3RlKG1pbihhZ2UsIG5hLnJtID0gVFJVRSksICItIiwgbWF4KGFnZSwgbmEucm0gPSBUUlVFKSksCiAgICBtZWFuX3Jpc2t0YWtpbmcgPSBtZWFuKHJpc2t0YWtpbmcsIG5hLnJtID0gVFJVRSkKICApCgojIERpc3BsYXkgdGhlIHRhYmxlCnRhYmxlX2RhdGEKYGBgCgojIENyZWF0ZSBhIG5ldyBjb2x1bW4gImFnZV9ncm91cCIgd2l0aCB0aGUgYWdlIGNhdGVnb3JpZXMKYGBge3J9CmNsZWFuZWRfZGF0YSRhZ2VjYXQgPC0gY3V0KAogIGNsZWFuZWRfZGF0YSRhZ2UsCiAgYnJlYWtzID0gYygxNSwgMjAsIDMwLCA0MCwgNTAsIDYwLCA3MCwgODAsIEluZiksICMgVGhlIGNhdGVnb3J5IGJvdW5kYXJpZXMKICBsYWJlbHMgPSBjKCIxNS0xOSIsICIyMC0yOSIsICIzMC0zOSIsICI0MC00OSIsICI1MC01OSIsICI2MC02OSIsICI3MC03OSIsICI4MCsiKSwgIyBUaGUgY2F0ZWdvcnkgbGFiZWxzCiAgcmlnaHQgPSBGQUxTRSAjIExlZnQgZW5kIChpbmNsdXNpdmUpLCByaWdodCBlbmQgKGV4Y2x1c2l2ZSkKKQoKIyBEaXNwbGF5IHRoZSBuZXcgY29sdW1uCmhlYWQoY2xlYW5lZF9kYXRhKQpgYGAKCiMgTnVtYmVyIG9mIHBhcnRpY2lwYW50cyBpbiBlYWNoIGFnZSBjYXRlZ29yeQpgYGB7cn0KIyBudW1iZXIgb2YgcGFydGljaXBhbnRzIGluIGVhY2ggYWdlIGNhdGVnb3J5CmFnZWNhdF9jb3VudHMgPC0gdGFibGUoY2xlYW5lZF9kYXRhJGFnZWNhdCkKCiMgRGlzcGxheSB0aGUgbnVtYmVyIG9mIHBhcnRpY2lwYW50cyBpbiB0aGUgYWdlIGNhdGVnb3JpZXMKcHJpbnQoYWdlY2F0X2NvdW50cykKYGBgCgoKIyBQZXJmb3JtIGEgY29ycmVsYXRpb24gYW5hbHlzaXMgb24gdmFyaWFibGVzIHBhdGllbmNlLCByaXNrdGFraW5nLCBhbHRydWlzbSBhbmQgdHJ1c3QKYGBge3J9CiMgQ2FsY3VsYXRlIHRoZSBjb3JyZWxhdGlvbiBtYXRyaXggd2l0aCBOQSByZW1vdmFsCmNvcnJlbGF0aW9uX21hdHJpeCA8LSBjb3IoY2xlYW5lZF9kYXRhWywgYygicGF0aWVuY2UiLCAicmlza3Rha2luZyIsICJhbHRydWlzbSIsICJ0cnVzdCIpXSwgdXNlID0gInBhaXJ3aXNlLmNvbXBsZXRlLm9icyIpCgojIFByaW50IHRoZSBjb3JyZWxhdGlvbiBtYXRyaXgKcHJpbnQoY29ycmVsYXRpb25fbWF0cml4KQoKYGBgCgojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKIyBjaGVja2luZyB0aGUgYXNzdW1wdGlvbnMgaW4gYSBsaW5lYXIgcmVncmVzc2lvbiAgCmBgYHtyfQojIFNjYXR0ZXJwbG90IHRvIGNoZWNrIGZvciBsaW5lYXJpdHkKZ2dwbG90KGNsZWFuZWRfZGF0YSwgYWVzKHggPSBhZ2UsIHkgPSByaXNrdGFraW5nKSkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgc2UgPSBGQUxTRSwgY29sb3IgPSAiYmx1ZSIpICsKICBsYWJzKHRpdGxlID0gIlNjYXR0ZXJwbG90IGZvciBMaW5lYXJpdHkgQ2hlY2siKQpgYGAKYGBge3J9CiMgUmVzaWR1YWwgdnMuIEZpdHRlZCBwbG90IHRvIGNoZWNrIGZvciBob21vc2tlZGFzdGljaXR5Cm1vZGVsIDwtIGxtKHJpc2t0YWtpbmcgfiBhZ2UsIGRhdGEgPSBjbGVhbmVkX2RhdGEpCmdncGxvdCgpICsKICBnZW9tX3BvaW50KGFlcyh4ID0gZml0dGVkKG1vZGVsKSwgeSA9IHJlc2lkdWFscyhtb2RlbCkpKSArCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMCwgbGluZXR5cGUgPSAiZGFzaGVkIiwgY29sb3IgPSAicmVkIikgKwogIGxhYnModGl0bGUgPSAiUmVzaWR1YWxzIHZzLiBGaXR0ZWQgVmFsdWVzIGZvciBIb21vc2tlZGFzdGljaXR5IENoZWNrIikKYGBgCgpgYGB7cn0KIyBRLVEgcGxvdCB0byBjaGVjayBmb3Igbm9ybWFsaXR5IG9mIHJlc2lkdWFscwpxcW5vcm0ocmVzaWR1YWxzKG1vZGVsKSkKcXFsaW5lKHJlc2lkdWFscyhtb2RlbCkpCmBgYAoKYGBge3J9CiMgQ29ycmVsYXRpb24gbWF0cml4IHRvIGNoZWNrIGZvciBtdWx0aWNvbGxpbmVhcml0eQpjb3IoY2xlYW5lZF9kYXRhW2MoImFnZSIsICJyaXNrdGFraW5nIildKQpgYGAKCmBgYHtyfQojIER1cmJpbi1XYXRzb24gdGVzdCBmb3IgYXV0b2NvcnJlbGF0aW9uCmR3dGVzdChtb2RlbCkKYGBgCgpgYGB7cn0KIyBSZXNpZHVhbCB2cy4gTGV2ZXJhZ2UgcGxvdCB0byBjaGVjayBmb3Igb3V0bGllcnMKZ2dwbG90KCkgKwogIGdlb21fcG9pbnQoYWVzKHggPSBoYXR2YWx1ZXMobW9kZWwpLCB5ID0gcmVzaWR1YWxzKG1vZGVsKSkpICsKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwLCBsaW5ldHlwZSA9ICJkYXNoZWQiLCBjb2xvciA9ICJyZWQiKSArCiAgbGFicyh0aXRsZSA9ICJSZXNpZHVhbHMgdnMuIExldmVyYWdlIGZvciBPdXRsaWVyIENoZWNrIikKYGBgCgojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKCgoKI1ByZXBhcmluZyBmb3IgbGluZWFyIHJlZ3Jlc3Npb24KYGBge3J9CiMgQ2hlY2sgZm9yIG1pc3NpbmcgdmFsdWVzIGluICdDb3VudHJ5JyBhbmQgJ1Jpc2t0YWtpbmcnIGNvbHVtbnMKbWlzc2luZ19jb3VudHJ5IDwtIGFueU5BKGNsZWFuZWRfZGF0YSRjb3VudHJ5KQptaXNzaW5nX3Jpc2t0YWtpbmcgPC0gYW55TkEoY2xlYW5lZF9kYXRhJHJpc2t0YWtpbmcpCgojIFByaW50IHRoZSByZXN1bHRzCmNhdCgiTWlzc2luZyB2YWx1ZXMgaW4gJ0NvdW50cnknOiAiLCBtaXNzaW5nX2NvdW50cnksICJcbiIpCmNhdCgiTWlzc2luZyB2YWx1ZXMgaW4gJ1Jpc2t0YWtpbmcnOiAiLCBtaXNzaW5nX3Jpc2t0YWtpbmcsICJcbiIpCgpgYGAKCgpgYGB7cn0KIyBDbGVhbiB0aGUgZGF0YSBieSByZW1vdmluZyByZWNvcmRzIHdpdGggbWlzc2luZyB2YWx1ZXMKY2xlYW5lZF9kYXRhIDwtIGdwc19kYXRhICU+JQogIGRyb3BfbmEoY291bnRyeSwgcmlza3Rha2luZywgYWdlKQoKIyBTcGxpdCB0aGUgZGF0YSBieSBjb3VudHJ5IGFuZCBwZXJmb3JtIGxpbmVhciByZWdyZXNzaW9uIGZvciBlYWNoIGNvdW50cnkKcmVncmVzc2lvbl9yZXN1bHRzIDwtIGNsZWFuZWRfZGF0YSAlPiUKICBncm91cF9ieShjb3VudHJ5KSAlPiUKICBkbyhtb2RlbCA9IGxtKHJpc2t0YWtpbmcgfiBhZ2UsIGRhdGEgPSAuKSkgJT4lCiAgc3VtbWFyaXplKAogICAgY291bnRyeSA9IGZpcnN0KGNvdW50cnkpLAogICAgaW50ZXJjZXB0ID0gc3VtbWFyeShtb2RlbCkkY29lZmZpY2llbnRzWzFdLAogICAgc2xvcGUgPSBzdW1tYXJ5KG1vZGVsKSRjb2VmZmljaWVudHNbMl0sCiAgICByX3NxdWFyZWQgPSBzdW1tYXJ5KG1vZGVsKSRyLnNxdWFyZWQKICApCgojIERpc3BsYXkgcmVncmVzc2lvbiByZXN1bHRzIGZvciBlYWNoIGNvdW50cnkKcHJpbnQocmVncmVzc2lvbl9yZXN1bHRzKQpgYGAKCgojIGFuYWx5emUgdGhlIHJlc3VsdHMgYnkgdXNpbmcgIkJhbGtlbmRpYWdyYW1tCmBgYHtyfQpnZ3Bsb3QoZGF0YSA9IHJlZ3Jlc3Npb25fcmVzdWx0cywgYWVzKHggPSBjb3VudHJ5LCB5ID0gaW50ZXJjZXB0KSkgKwogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBmaWxsID0gImJsdWUiKSArCiAgbGFicyh0aXRsZSA9ICJJbnRlcmNlcHRzIGZvciBSaXNrdGFraW5nIGJ5IENvdW50cnkiLCB4ID0gIkNvdW50cnkiLCB5ID0gIkludGVyY2VwdCBWYWx1ZSIpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwLCBoanVzdCA9IDEpKQpgYGAKIyBWaWV3IHRoZSBjb3VudHJpZXMgd2l0aCBpbnRlcmNlcHQgdmFsdWVzIG92ZXIgMC43NQpgYGB7cn0KaGlnaF9pbnRlcmNlcHRfY291bnRyaWVzIDwtIHN1YnNldChyZWdyZXNzaW9uX3Jlc3VsdHMsIGludGVyY2VwdCA+IDAuNzUpCgojIFZpZXcgdGhlIGNvdW50cmllcyB3aXRoIGludGVyY2VwdCB2YWx1ZXMgb3ZlciAwLjc1CnByaW50KGhpZ2hfaW50ZXJjZXB0X2NvdW50cmllcykKYGBgCgoKIyBTY2F0dGVycGxvdHMgZm9yICdoaWdoX2ludGVyY2VwdF9jb3VudHJpZXMnIGNvbnRhaW5zIHRoZSB0b3AgMTcgY291bnRyaWVzCmBgYHtyfQojIENyZWF0ZSBzY2F0dGVycGxvdHMgd2l0aCByZWdyZXNzaW9uIGxpbmVzIGZvciBjb3VudHJpZXMgd2l0aCBpbnRlcmNlcHQgPiAwLjc1IGFuZCBzbWFsbGVyIHBvaW50cwpwbG90cyA8LSBsYXBwbHkoMTpucm93KHJlZ3Jlc3Npb25fcmVzdWx0cyksIGZ1bmN0aW9uKGkpIHsKICBjb3VudHJ5IDwtIHJlZ3Jlc3Npb25fcmVzdWx0cyRjb3VudHJ5W2ldCiAgaW50ZXJjZXB0IDwtIHJlZ3Jlc3Npb25fcmVzdWx0cyRpbnRlcmNlcHRbaV0KICAKICBpZiAoaW50ZXJjZXB0ID4gMC43NSkgewogICAgcCA8LSBnZ3Bsb3Qoc3Vic2V0KGNsZWFuZWRfZGF0YSwgY291bnRyeSA9PSBjb3VudHJ5KSwgYWVzKHggPSBhZ2UsIHkgPSByaXNrdGFraW5nKSkgKwogICAgICBnZW9tX3BvaW50KHNpemUgPSAwLjUpICsgICMgU2V0IHRoZSBzaXplIHRvIGEgc21hbGxlciB2YWx1ZSAoZS5nLiwgMikKICAgICAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgZm9ybXVsYSA9IHkgfiB4LCBzZSA9IEZBTFNFLCBjb2xvciA9ICJibHVlIikgKwogICAgICBsYWJzKHRpdGxlID0gcGFzdGUoIkxpbmVhciBSZWdyZXNzaW9uIGZvciIsIGNvdW50cnkpLAogICAgICAgICAgIHN1YnRpdGxlID0gcGFzdGUoIkludGVyY2VwdDoiLCByb3VuZChpbnRlcmNlcHQsIDIpKSkKICAgIHByaW50KHApCiAgfQp9KQoKIyBTYXZlIHRoZSBwbG90cyBpbiBhIGRpcmVjdG9yeQpkaXIuY3JlYXRlKCJpbmRpdmlkdWFsX2NvdW50cnlfcGxvdHMiLCBzaG93V2FybmluZ3MgPSBGQUxTRSkKc2V0d2QoImluZGl2aWR1YWxfY291bnRyeV9wbG90cyIpCgpmb3IgKGkgaW4gc2VxX2Fsb25nKHBsb3RzKSkgewogIGZpbGVuYW1lIDwtIHBhc3RlMCgicGxvdF8iLCBpLCAiLnBuZyIpCiAgZ2dzYXZlKGZpbGVuYW1lLCBwbG90ID0gcGxvdHNbW2ldXSwgd2lkdGggPSA4LCBoZWlnaHQgPSA2KQp9CgojIFN3aXRjaCBiYWNrIHRvIHRoZSBvcmlnaW5hbCB3b3JraW5nIGRpcmVjdG9yeQpzZXR3ZCgiLi4iKQoKcHJpbnQoIkluZGl2aWR1YWwgcGxvdHMgZm9yIGNvdW50cmllcyB3aXRoIGludGVyY2VwdCA+IDAuNzUgYW5kIHNtYWxsZXIgcG9pbnRzIGFyZSBzYXZlZCBpbiB0aGUgJ2luZGl2aWR1YWxfY291bnRyeV9wbG90cycgZGlyZWN0b3J5LiIpCmBgYAoKIyBDcmVhdGUgc2NhdHRlcnBsb3RzIHdpdGggcmVncmVzc2lvbiBsaW5lcyBmb3IgaW5kaXZpZHVhbCBjb3VudHJpZXMKYGBge3J9CiMgRXhhbXBsZXMgZm9yIGNvdW50cmllcwpyZWdyZXNzaW9uX3Jlc3VsdHMgPC0gZGF0YS5mcmFtZSgKICBjb3VudHJ5ID0gYygiQWxnZXJpYSIsICJBcmdlbnRpbmEiLCAiQXVzdHJpYSIpLAogIGludGVyY2VwdCA9IGMoMC45MjA1MzQyMiwgMC41MTY5ODgyMiwgMC40MjYwNjY4NCksCiAgc2xvcGUgPSBjKC0wLjAxNDY2NDE4MDEsIC0wLjAxMTU1Njk2MjMsIC0wLjAxMDg3NjMwNDIpLAogIHJfc3F1YXJlZCA9IGMoNS4yMzI1MjllLTAyLCA1LjYzODI3MWUtMDIsIDMuNTM5ODEwZS0wMgkpCikKCiMgQ3JlYXRlIHNjYXR0ZXJwbG90cyB3aXRoIHJlZ3Jlc3Npb24gbGluZXMgZm9yIGVhY2ggY291bnRyeQpwbG90cyA8LSBsYXBwbHkoc2VxX2xlbihucm93KHJlZ3Jlc3Npb25fcmVzdWx0cykpLCBmdW5jdGlvbihpKSB7CiAgY291bnRyeSA8LSByZWdyZXNzaW9uX3Jlc3VsdHMkY291bnRyeVtpXQogIGludGVyY2VwdCA8LSByZWdyZXNzaW9uX3Jlc3VsdHMkaW50ZXJjZXB0W2ldCiAgc2xvcGUgPC0gcmVncmVzc2lvbl9yZXN1bHRzJHNsb3BlW2ldCiAgcl9zcXVhcmVkIDwtIHJlZ3Jlc3Npb25fcmVzdWx0cyRyX3NxdWFyZWRbaV0KICAKICBwIDwtIGdncGxvdChzdWJzZXQoY2xlYW5lZF9kYXRhLCBjb3VudHJ5ID09IGNvdW50cnkpLCBhZXMoeCA9IGFnZSwgeSA9IHJpc2t0YWtpbmcpKSArCiAgICBnZW9tX3BvaW50KCkgKwogICAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgZm9ybXVsYSA9IHkgfiB4LCBzZSA9IEZBTFNFLCBjb2xvciA9ICJibHVlIikgKwogICAgbGFicyh0aXRsZSA9IHBhc3RlKCJMaW5lYXIgUmVncmVzc2lvbiBmb3IiLCBjb3VudHJ5KSwKICAgICAgICAgc3VidGl0bGUgPSBwYXN0ZSgiSW50ZXJjZXB0OiIsIHJvdW5kKGludGVyY2VwdCwgMiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICJTbG9wZToiLCByb3VuZChzbG9wZSwgMiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICJSLXNxdWFyZWQ6Iiwgcm91bmQocl9zcXVhcmVkLCAyKSkpCiAgcHJpbnQocCkKfSkKCiMgU2F2ZSB0aGUgcGxvdHMgaW4gYSBkaXJlY3RvcnkKZGlyLmNyZWF0ZSgiaW5kaXZpZHVhbF9jb3VudHJ5X3Bsb3RzIiwgc2hvd1dhcm5pbmdzID0gRkFMU0UpCnNldHdkKCJpbmRpdmlkdWFsX2NvdW50cnlfcGxvdHMiKQoKZm9yIChpIGluIHNlcV9hbG9uZyhwbG90cykpIHsKICBmaWxlbmFtZSA8LSBwYXN0ZTAoInBsb3RfIiwgaSwgIi5wbmciKQogIGdnc2F2ZShmaWxlbmFtZSwgcGxvdCA9IHBsb3RzW1tpXV0sIHdpZHRoID0gOCwgaGVpZ2h0ID0gNikKfQoKIyBTd2l0Y2ggYmFjayB0byB0aGUgb3JpZ2luYWwgd29ya2luZyBkaXJlY3RvcnkKc2V0d2QoIi4uIikKCnByaW50KCJJbmRpdmlkdWFsIHBsb3RzIGFyZSBzYXZlZCBpbiB0aGUgJ2luZGl2aWR1YWxfY291bnRyeV9wbG90cycgZGlyZWN0b3J5LiIpCmBgYAoKIyBDcmVhdGUgYSBzY2F0dGVycGxvdCB3aXRoIHNlcGFyYXRlIHJlZ3Jlc3Npb24gbGluZXMgZm9yIGVhY2ggY291bnRyeQpgYGB7cn0KZ2dwbG90KGNsZWFuZWRfZGF0YSwgYWVzKHggPSBhZ2UsIHkgPSByaXNrdGFraW5nLCBjb2xvciA9IGNvdW50cnkpKSArCiAgZ2VvbV9wb2ludChzaXplID0gMC4yKSArICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBBZGp1c3QgcG9pbnQgc2l6ZQogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIHNlID0gRkFMU0UsIHNpemUgPSAwLjUsIGxpbmV0eXBlID0gInNvbGlkIikgKyAjIEFkanVzdCBsaW5lIHNpemUgYW5kIHR5cGUKICBsYWJzKHRpdGxlID0gIlNjYXR0ZXJwbG90IHdpdGggUmVncmVzc2lvbiBMaW5lcyBmb3Igcmlza3Rha2luZyBhbmQgYWdlIGJ5IENvdW50cnkiLCAKICAgICAgIHggPSAiQWdlIiwgeSA9ICJSaXNrdGFraW5nIikgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iLCAgICAgICAgICAgICAgIyBNb3ZlIHRoZSBsZWdlbmQgYmVsb3cgdGhlIGdyYXBoCiAgICAgICAgbGVnZW5kLmtleS5zaXplID0gdW5pdCgwLjEsICJpbiIpKSAgICAgICMgQWRqdXN0IHRoZSBzaXplIG9mIHRoZSBsZWdlbmQga2V5CmBgYAoKIyBTY2F0dGVycGxvdCB3aXRoIGluY2x1ZGUgYm90aCBpbmRpdmlkdWFsIGNvdW50cnkgcmVncmVzc2lvbiBsaW5lcyBhbmQgYW4gb3ZlcmFsbCByZWdyZXNzaW9uIGxpbmUKYGBge3J9CiMgQ2FsY3VsYXRlIHRoZSBvdmVyYWxsIHJlZ3Jlc3Npb24gbGluZQpvdmVyYWxsX2xtIDwtIGxtKHJpc2t0YWtpbmcgfiBhZ2UsIGRhdGEgPSBjbGVhbmVkX2RhdGEpCgojIENyZWF0ZSBhIHNjYXR0ZXJwbG90IHdpdGggc2VwYXJhdGUgcmVncmVzc2lvbiBsaW5lcyBmb3IgZWFjaCBjb3VudHJ5CiMgYW5kIGFuIG92ZXJhbGwgcmVncmVzc2lvbiBsaW5lCmdncGxvdChjbGVhbmVkX2RhdGEsIGFlcyh4ID0gYWdlLCB5ID0gcmlza3Rha2luZywgY29sb3IgPSBjb3VudHJ5KSkgKwogIGdlb21fcG9pbnQoc2l6ZSA9IDAuNSkgKyAgICAgICAgICAgICAgICAgICAgICAjIEFkanVzdCBwb2ludCBzaXplCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgc2UgPSBGQUxTRSwgc2l6ZSA9IDAuNSkgKyAjIFNvbGlkIGxpbmUgZm9yIGluZGl2aWR1YWwgY291bnRyaWVzCiAgZ2VvbV9hYmxpbmUoaW50ZXJjZXB0ID0gY29lZihvdmVyYWxsX2xtKVsxXSwgc2xvcGUgPSBjb2VmKG92ZXJhbGxfbG0pWzJdLCAKICAgICAgICAgICAgICBjb2xvciA9ICJyZWQiLCBzaXplID0gMSkgKyAjIEFkZCB0aGUgb3ZlcmFsbCByZWdyZXNzaW9uIGxpbmUgaW4gcmVkCiAgbGFicyh0aXRsZSA9ICJTY2F0dGVycGxvdCB3aXRoIFJlZ3Jlc3Npb24gTGluZXMgZm9yIHJpc2t0YWtpbmcgYW5kIGFnZSBieSBDb3VudHJ5IiwgCiAgICAgICB4ID0gIkFnZSIsIHkgPSAiUmlza3Rha2luZyIpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIiwgICAgICAgICAgIyBNb3ZlIHRoZSBsZWdlbmQgYmVsb3cgdGhlIGdyYXBoCiAgICAgICAgbGVnZW5kLmtleS5zaXplID0gdW5pdCgwLjEsICJpbiIpKSAgIyBBZGp1c3QgdGhlIHNpemUgb2YgdGhlIGxlZ2VuZCBrZXkKYGBgCgoK